package com.ajun.es.index;

import cn.hutool.core.collection.CollUtil;
import com.ajun.common.ESConstants;
import com.ajun.common.util.EsClientFactory;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.platform.commons.annotation.Testable;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * ES Index Tutorial
 *
 * @author AJun
 * @date 2021-07-20
 */
@Testable
@Slf4j
public class IndexTutorial {

    RestHighLevelClient client;
    final String USER_INDEX = ESConstants.USER_INDEX;

    @BeforeEach
    void init() {
        client = EsClientFactory.esClient();
    }

    @AfterEach
    void destroy() {
        EsClientFactory.close();
    }

    /**
     * 同步创建索引
     */
    @Test
    void testSyncCreateIndex() throws IOException {
        if (indexExists(USER_INDEX)) {
            log.error("{} 索引已存在", USER_INDEX);
            return;
        }

        CreateIndexRequest request = new CreateIndexRequest(USER_INDEX);
        CreateIndexResponse response;
        response = client.indices().create(request, RequestOptions.DEFAULT);
        logNotify(response.isAcknowledged());
    }

    /**
     * 异步创建索引
     */
    @Test
    void testAsyncCreateIndex() throws InterruptedException {
        if (indexExists(USER_INDEX)) {
            log.error("{} 索引已存在", USER_INDEX);
            return;
        }

        CreateIndexRequest request = new CreateIndexRequest(USER_INDEX);
        client.indices().createAsync(request, RequestOptions.DEFAULT, new ActionListener<CreateIndexResponse>() {
            @Override
            public void onResponse(CreateIndexResponse createIndexResponse) {
                logNotify(createIndexResponse.isAcknowledged());
            }

            @Override
            public void onFailure(Exception e) {
                logError(e);
            }
        });

        // 由于异步,方法执行完毕后未得到响应就关闭释放了资源,这里睡1s,得到响应后再释放资源
        TimeUnit.SECONDS.sleep(1);
    }

    /**
     * 查询索引
     */
    @Test
    void testGetIndex() throws IOException, InterruptedException {
        if (!indexExists(USER_INDEX)) {
            log.error("{} 索引不存在", USER_INDEX);
            return;
        }

        // 获取索引请求
        GetIndexRequest request = new GetIndexRequest(USER_INDEX);

        // 同步获取索引信息
        GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
        log.debug("索引信息 Aliases: {}", response.getAliases());
        log.debug("索引信息 Mappings: {}", response.getMappings());
        log.debug("索引信息 DataStreams: {}", response.getDataStreams());
        log.debug("索引信息 DefaultSettings: {}", response.getDefaultSettings());
        log.debug("索引信息 Settings: {}", response.getSettings());
        log.debug("索引信息 Indices: {}", CollUtil.toList(response.getIndices()));

        // 异步获取索引信息
        client.indices().getAsync(request, RequestOptions.DEFAULT, new ActionListener<GetIndexResponse>() {
            @Override
            public void onResponse(GetIndexResponse getIndexResponse) {
                log.debug("索引信息 Aliases: {}", getIndexResponse.getAliases());
                log.debug("索引信息 Mappings: {}", getIndexResponse.getMappings());
                log.debug("索引信息 DataStreams: {}", getIndexResponse.getDataStreams());
                log.debug("索引信息 DefaultSettings: {}", getIndexResponse.getDefaultSettings());
                log.debug("索引信息 Settings: {}", getIndexResponse.getSettings());
                log.debug("索引信息 Indices: {}", CollUtil.toList(getIndexResponse.getIndices()));
            }

            @Override
            public void onFailure(Exception e) {
                logError(e);
            }
        });

        // 由于异步,方法执行完毕后未得到响应就关闭释放了资源,这里睡1s,得到响应后再释放资源
        TimeUnit.SECONDS.sleep(1);
    }

    /**
     * 删除索引
     */
    @Test
    void testDeleteIndex() throws IOException, InterruptedException {
        if (!indexExists(USER_INDEX)) {
            log.error("{} 索引不存在", USER_INDEX);
            return;
        }

        // 删除索引请求
        DeleteIndexRequest request = new DeleteIndexRequest(USER_INDEX);

        // 同步删除索引
        AcknowledgedResponse deleteIndexResponse = client.indices().delete(request, RequestOptions.DEFAULT);
        logNotify(deleteIndexResponse.isAcknowledged());

        // 异步删除索引
        client.indices().deleteAsync(request, RequestOptions.DEFAULT, new ActionListener<AcknowledgedResponse>() {
            @Override
            public void onResponse(AcknowledgedResponse acknowledgedResponse) {
                logNotify(acknowledgedResponse.isAcknowledged());
            }

            @Override
            public void onFailure(Exception e) {
                logError(e);
            }
        });

        // 由于异步,方法执行完毕后未得到响应就关闭释放了资源,这里睡1s,得到响应后再释放资源
        TimeUnit.SECONDS.sleep(1);
    }

    boolean indexExists(String indexName) {
        boolean exists = false;
        try {
            exists = client.indices().exists(new GetIndexRequest(indexName), RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return exists;
    }

    void logNotify(Boolean acknowledged) {
        log.debug("索引操作: {}", acknowledged ? "成功" : "失败");
    }

    void logError(Exception ex) {
        log.error("索引操作失败,异常信息: {}", ex.getMessage());
    }
}
